package grammer.phrase;

import grammer.DirectObject;
import grammer.LocalObject;
import grammer.ModalObject;
import grammer.Predicate;
import grammer.Subject;
import grammer.Type1TimeObject;
import grammer.Type2TimeObject;
import grammer.WeatherSubject;
import grammer.components.Component;
import grammer.components.LocationEnum;
import grammer.components.ObjectEnum;
import grammer.components.PowerEnum;
import grammer.components.PredicateEnum;
import grammer.components.SubjectEnum;
import grammer.components.TimeEnum;
import grammer.components.WeatherEnum;

import java.util.Vector;

import person.PersonAchive;

public class PhraseBuilder {

	/**
	 * each sentence has 1 predicate, 1 location and 1 timeStamp;
	 */
	private boolean hasPredicate = false, hasLocation = false, hasTime = false,
			isWeather = false;
	private Component intensity = PowerEnum.GENERIC_POWER;

	private Component location = LocationEnum.GENERIC_LOCATION;
	private Phrase nextPhrase;
	private int numberOfParts = 0;

	private Component object = ObjectEnum.GENERIC_OBJECT;

	/**
	 * restSentence()
	 */
	private Component predicate = PredicateEnum.GENERIC_PREDICATE;

	/**
	 * firstMember();
	 */
	private Component subject = SubjectEnum.GENERIC_SUBJECT;

	private Component time = TimeEnum.GENERIC_TIME;
	private Component weather = WeatherEnum.GENERIC_WEATHER;

	public Phrase buildPhrase(Vector<String> line, int lineNumber) {
		init();
		String nextComponent = line.get(0);
		firstMember(nextComponent, lineNumber);
		restSentence(line, lineNumber);
		if(flag) return null;
		return nextPhrase;
	}
	
	boolean flag=false;

	private void firstMember(String nextComponent, int lineNumber) {
		if (PersonAchive.getPerson(nextComponent) != null) {
			Subject newSubject = new Subject(subject.match(nextComponent));
			newSubject.setName(nextComponent);
			nextPhrase.add(newSubject);
			numberOfParts++;
		} else {
			Component c = weather.match(nextComponent);
			if (c != null) {
				WeatherSubject newWeather = new WeatherSubject(c,nextComponent);
				nextPhrase.add(newWeather);
				numberOfParts++;
				isWeather = true;
				nextPhrase.setWeather(true);
			} else {
				System.out.println("Error at Scenario line " + lineNumber
						+ ": Person does not exist!");
				flag=true;
			}
		}

	}

	private void init() {
		nextPhrase = new Phrase();
		flag=false;
		numberOfParts = 0;
		hasLocation = false;
		hasPredicate = false;
		hasTime = false;
		isWeather = false;
	}

	private void restSentence(Vector<String> line, int lineNumber) {
		String nextComponent;
		for (int i = 1; i < line.size(); i++) {
			nextComponent = line.get(i);
			Component c;
			c = predicate.match(nextComponent);
			if (c != null && !hasPredicate) {
				Predicate newPred = new Predicate(c);
				nextPhrase.add(newPred);
				numberOfParts++;
				hasPredicate = true;
			} else {
				c = location.match(nextComponent);
				if (c != null && !hasLocation) {
					LocalObject local = new LocalObject(c);
					local.setLocation(nextComponent);
					nextPhrase.add(local);
					numberOfParts++;
					hasLocation = true;
				} else {
					c = time.match(nextComponent);
					if (c != null && !hasTime) {
						if (((TimeEnum) c) == TimeEnum.AT_X) {
							Type1TimeObject t1to = new Type1TimeObject(c);
							t1to.setTimeString(nextComponent);
							nextPhrase.add(t1to);
							numberOfParts++;
						} else {
							Type2TimeObject t2to = new Type2TimeObject(c);
							t2to.setTimesString(nextComponent);
							nextPhrase.add(t2to);
							numberOfParts++;
						}
						hasTime = true;
					} else {
						c = object.match(nextComponent);
						if (c != null) {
							DirectObject dobj = new DirectObject(c);
							nextPhrase.add(dobj);
							numberOfParts++;
						} else {
							c = intensity.match(nextComponent);
							if (c != null) {
								ModalObject mobj2 = new ModalObject(c);
								nextPhrase.add(mobj2);
								numberOfParts++;
							} else {
								System.out.println("Error at component: "
										+ line.get(i) + " line: " + lineNumber);
							}
						}
					}
				}
			}
			/** Closing else 1-4 **/

		}
		/** Closing for **/
		if (numberOfParts != line.size()) {
			flag=true;
			System.out.println("Syntax error at line: " + lineNumber
					+ " missing component");
		}

		if (hasPredicate == false && !isWeather)
		{
			System.out.println("Syntax error at line: " + lineNumber
					+ " - no predicate");
			flag=true;
		}
		if (hasTime == false)
		{
			System.out.println("Syntax error at line: " + lineNumber
					+ " - no time specified");
			flag=true;
		}

	}
}
